package com.rivues.util.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import junit.framework.Assert;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.csvreader.CsvWriter;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.rivues.core.RivuDataContext;
import com.rivues.module.platform.web.model.AnalyzerReport;
import com.rivues.module.platform.web.model.AnalyzerReportModel;
import com.rivues.module.platform.web.model.JobDetail;
import com.rivues.module.platform.web.model.ReportFilter;
import com.rivues.util.RivuTools;
import com.rivues.util.data.FirstTitle;
import com.rivues.util.data.ReportData;
import com.rivues.util.data.CubeData;
import com.rivues.util.data.Level;
import com.rivues.util.data.ValueData;
import com.rivues.util.service.cache.CacheHelper;

/**
 * 导出Excel
 * @author Jason Chen
 *
 */
public class RivuXMLUtil implements ExportFile{
	private static final Logger log=Logger.getLogger(RivuXMLUtil.class);
	
	private ReportData reportData;
	private AnalyzerReportModel model;
	private AnalyzerReport report ;
	private Document document;
	
	private JobDetail job;
	
	private Element root;
	
	private String headTitle ="报表";
	
	private String startTime ="";
	
	private String endTime = "";
	
	private Object cachesize = null;
	
	private Element data;
	
	int  page = 1 ;
	
	private OutputStream out ; 
	XMLWriter writer = null;  
	
	public RivuXMLUtil() {
		this.model = model;
		this.report = report;
		this.out = out ;
		document = DocumentHelper.createDocument();
		root = document.addElement("reportdata"); 
	}
	public RivuXMLUtil(AnalyzerReportModel model , AnalyzerReport report , OutputStream out){
		this.model = model;
		this.reportData = this.model.getReportData();
		this.report = report ;
		this.out = out ;
		if(!StringUtils.isBlank(report.getReportname())){
			this.headTitle = report.getReportname();
		}
		document = DocumentHelper.createDocument();
		root = document.addElement("reportdata"); 
	}
	
	/**
	 * 构建Excel
	 * @param fileName
	 * @throws IOException 
	 */
	public void createFile(boolean limit) throws Exception{
		this.createHead();
		this.createSubHead();
		this.createTitle();
		this.createContent();
	}
	
	/**
	 * 构建头部
	 */
	private void createHead(){
		Element name = root.addElement("name");
		name.setText(headTitle);
	}
	
	/**
	 * 构建副标题
	 */
	private void createSubHead(){
		StringBuffer strb = new StringBuffer();
		if(this.model.getFilters()!=null && this.model.getFilters().size()>0){
			for(ReportFilter filter : this.model.getFilters()){
				if(!filter.isChild()){
					if(!RivuDataContext.ReportCompareEnum.COMPARE.toString().equals(filter.getValuefiltertype())){
						if(StringUtils.isBlank(filter.getCurvalue())){
							strb.append(filter.getName()).append(":").append(RivuTools.getDefaultValue(filter , RivuDataContext.ReportCompareEnum.COMPARE.toString() , null)).append("                      ") ;
						}
					}else{
						if(!StringUtils.isBlank(filter.getCurstartvalue())&&!StringUtils.isBlank(filter.getCurendvalue())){
							strb.append(filter.getName()).append(":").append(RivuTools.getDefaultValue(filter , RivuDataContext.ReportCompareEnum.START.toString() , null)).append(" ~ ").append(RivuTools.getDefaultValue(filter , RivuDataContext.ReportCompareEnum.END.toString() , null)).append("                      ") ;
						}
					}
					
				}
			}
		}else{
			strb.append("报表生成日期:").append(getNowDate()) ;
		}
		
		Element description = root.addElement("description");
		description.setText(strb.toString());
	}
	
	/**
	 * 构建标题
	 */
	@SuppressWarnings("deprecation")
	private void createTitle(){
		Element titles = root.addElement("titles");
		Element list_title = null;
		if(reportData.getRow() != null && reportData.getRow().getFirstTitle()!=null){
			for(FirstTitle firstTitle:reportData.getRow().getFirstTitle()){
				list_title = titles.addElement("title");
				list_title.setText(firstTitle.getName());
			}
		}
		List<List<Level>> title = reportData.getCol().getTitle();
		if(title!=null){
			for(List<Level> levelList : title){
				for(Level level : levelList){
					list_title = titles.addElement("title");
					list_title.setText(level.getName());
				}
			}
		}
		data = root.addElement("data");
	}
	
	public void createRow(Level level,Element row){
		Element childelement = row.addElement("level");
		Element val = childelement.addElement("value");
		childelement.setAttributeValue("colname", level.getDimname());
		val.setText(String.valueOf(level.getName()));
		if(level.getValueData()!=null&&level.getValueData().size()>0){
			Element element= childelement.addElement("measures");
			Element measure = null;
			for (ValueData data : level.getValueData()) {
				measure = element.addElement("measure");
				measure.setAttributeValue("colname", data.getName());
				measure.setText(data.toString());
			}
		}
		if(level.getChilderen()!=null&&level.getChilderen().size()>0){
			for (Level children : level.getChilderen()) {
				this.createRow(children, childelement);
			}
		}
	}
	
	/**
	 * 构建内容
	 */
	private synchronized void createContent(){
		
		Element val = null;
		if(reportData.getRow()!=null){
			this.createRow(reportData.getRow(), data);
			
		}else{
			Element list = null;
			CubeData cdata=(CubeData)reportData;
			List<List<ValueData>> dataList = reportData.getData();
			for(int r =0;cdata.getItem()!=null && r<cdata.getItem().size();r++){
				list = data.addElement("list");
				StringBuffer sb = new StringBuffer();
				for(int c =1;r<dataList.size() && c<dataList.get(r).size()+1;c++){
					if(sb.toString().length()>0){sb.append(",");}
					sb.append(String.valueOf(dataList.get(r).get(c-1)));
				}
				list.setText(sb.toString());
			}
			
			
		}
	}
	
	private String getNowDate(){
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		return sf.format(new Date());
	}
	
	
	private boolean checkIsNumber(String str){
		Pattern p = Pattern.compile("^(-?\\d+)(\\.\\d+)?$");
		Matcher m = p.matcher(str);
		return m.matches();
	}

	
	public void setStartTime(String startTime) {
		this.startTime = startTime;
	}

	public void setEndTime(String endTime) {
		this.endTime = endTime;
	}

	public String getHeadTitle() {
		// TODO Auto-generated method stub
		return this.headTitle;
	}

	public String getStartTime() {
		// TODO Auto-generated method stub
		return this.startTime;
	}

	public String getEndTime() {
		// TODO Auto-generated method stub
		return this.endTime;
	}

	public void setHeadTitle(String title) {
		this.headTitle = title ;
	}

	@Override
	public void createSheet(String sheetName) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setReportData(ReportData reportData) throws Exception {
		// TODO Auto-generated method stub
		this.reportData = reportData;
	}

	@Override
	public void setModel(AnalyzerReportModel model) throws Exception {
		// TODO Auto-generated method stub
		this.model = model;
	}

	@Override
	public void setReport(AnalyzerReport report) throws Exception {
		// TODO Auto-generated method stub
		this.report = report;
	}

	public void setRowNum(int rowNum) {
	}
	@Override
	public int getRowNum() throws Exception {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void close() {
		try {
			OutputFormat format = OutputFormat.createPrettyPrint();  
			format.setEncoding("UTF-8");// 设置XML文件的编码格式,如果有中文可设置为GBK或UTF-8 
			writer = new XMLWriter(out, format); 
			writer.write(document);  
			writer.close();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	@Override
	public void setPage(int page) throws Exception {
		// TODO Auto-generated method stub
		this.page=page;
	}
	@Override
	public void setOut(OutputStream out) throws Exception {
		// TODO Auto-generated method stub
		this.out = out;
	}
	@Override
	public int getPage() throws Exception {
		// TODO Auto-generated method stub
		return this.page;
	}
	@Override
	public void setJobDetail(JobDetail job) {
		// TODO Auto-generated method stub
		this.job = job;
	}
	@Override
	public JobDetail getJobDetail() {
		// TODO Auto-generated method stub
		return this.job;
	}
	@Override
	public void writeHead(ReportData reportData) throws Exception {
		if(this.reportData == null){
			this.reportData = reportData ;
		}
		this.createHead();
		this.createSubHead();
		this.createTitle();
	}
	@Override
	public synchronized void writeRow(ReportData reportData) throws Exception {
		if(reportData!=null){
			this.reportData = reportData ;
			this.createContent();
		}
	}
	@Override
	public ReportData getReportData() {
		// TODO Auto-generated method stub
		return this.reportData;
	}
	@Override
	public void createFile(String filename) throws Exception {
		// TODO Auto-generated method stub
		
	}

}
